(($) => {
	window.SearchController = (function () {
		return new function () {
			this._isInsearch = false;
			this.SEARCH_ALL = 2;
			this.SEARCH_CURRENT = 1;
			this._searchMode = this.SEARCH_ALL;
			this._searchMacthBlocks = [];
			this._searchMacthPages = [];
			this._searchText = '';
			this._keywordCount = 0;
			this._keywordCountCurrent = 0;
			
			
			this.setIsInSearch = function (b) {
				this._isInsearch = b;
				return this;
			};
			
			this.isSearchAll = function () {
				return this._searchMode == this.SEARCH_ALL;
			};
			
			this.setSearchMode = function (mode) {
				this._searchMode = mode;
				return this;
			};
			
			this.isSearchCurrent = function () {
				return this._searchMode == this.SEARCH_CURRENT;
			};
			
			this.isInSearch = function () {
				return this._isInsearch;
			};
			
			this.setMatchBlocks = function (blocks) {
				this._searchMacthBlocks = blocks;
			};
			
			this.isMatchBlock = function (blockId) {
				return this._searchMacthBlocks.indexOf(blockId) !== -1;
			};
			
			this.setMatchPages = function (pages) {
				this._searchMacthPages = pages;
			};
			
			this.isMatchPage = function (pageId) {
				return this._searchMacthPages.indexOf(pageId) !== -1;
			};
			
			this.setSearchText = function (text) {
				this._searchText = text;
				return this;
			};
			
			this.resetKeywordCount = function () {
				this._keywordCount = 0;
				return this;
			};
			
			this.getKeywordCount = function () {
				return this._keywordCount;
			};
			
			this.getKeywordCountCurrent = function () {
				return this._keywordCountCurrent;
			};
			
			this.resetKeywordCountCurrent = function () {
				this._keywordCountCurrent = 0;
				return this;
			};
			
			this.increaseKeywordCountCurrent= function () {
				this._keywordCountCurrent++;
				return this;
			};
			
			this.updateSearchKeyword = function () {
				let left_search_tip = document.getElementById('left_search_tip');
				let content_search_tip = document.getElementById('content_search_tip');
				let content_search_kw_count = document.getElementById('content_search_kw_count');
				let left_search_tip_keyword = document.getElementById('left_search_tip_keyword');
				let content_search_tip_keyword = document.getElementById('content_search_tip_keyword');
				
				if(this.isInSearch()) {
					if(this.isSearchAll()) {
						left_search_tip.style.display = "block";
					} else {
						left_search_tip.style.display = "none";
					}
				
					content_search_tip.style.display = "block";
					content_search_kw_count.innerHTML = this.getKeywordCount();
					$('#page_content').addClass('search');
				} else {
					left_search_tip.style.display = "none";
					content_search_tip.style.display = "none";
					$('#page_content').removeClass('search');
				}
				
				left_search_tip_keyword.innerHTML = Core.htmlEncode(this._searchText);
				content_search_tip_keyword.innerHTML = Core.htmlEncode(this._searchText);
			};
			
			this.quitSearch = function () {
				this.setIsInSearch(false).updateSearchKeyword();
				LeftTree.render(CategoryHelper.getTreeData());
			};
			
			/**
			 * 执行搜索
			 * @param text
			 * @param mode
			 */
			this.search = function (text, mode) {
				let liketext = text.replace(/\//g, '//').replace(/%/g, '/%').replace(/_/g, '/_');
				let likeexpr = "%" + liketext + "%";
				
				mode = mode ? mode : this.SEARCH_ALL;
				this.setIsInSearch(true)
					.setSearchMode(mode)
					.setSearchText(text)
				;
				
				let blockCollector = new BlockModelCollector();
				blockCollector
					.where([
						[
							COL('type').eq(BlockModel.TYPE.PASSWORD), AND, [
								COL('label').like(likeexpr), OR, COL('comment').like(likeexpr)
							]
						],
						OR,
						[
							COL('type').neq(BlockModel.TYPE.PASSWORD), AND, [
								COL('value').like(likeexpr), OR,
								COL('label').like(likeexpr), OR,
								COL('comment').like(likeexpr)
							]
						]
					])
					.groupBy('id')
				;
				
				let blocks = blockCollector.load().getData().map(r => r.id);
				blocks = Array.from(new Set(blocks));
				this.setMatchBlocks(blocks);
				
				if(this.isSearchAll()) {
					let pages = blockCollector.load().getData().map(r => r.page_id);
					pages = Array.from(new Set(pages));
					this.setMatchPages(pages);
					LeftTree.render(CategoryHelper.getTreeData(null, pages));
				}
			};
			
			this.hideEmptyGroup = function (hide) {
				hide = typeof hide == "undefined" ? $('#hide_not_match_result').prop('checked') : hide;
				let opacity = 0.5;
				let page_content = $('#page_content');
				page_content.find('.article-item .lists li').show();
				page_content.find('.article-item').show();
				let nomatchs = page_content.find('.article-item .lists li[data-search-match=false]');
				nomatchs.css('opacity', opacity);
				
				if(hide) {
					nomatchs.hide()
				}
				
				page_content.find('.article-item').each(function () {
					if($(this).data('searchMatch')) {
						$(this).find('.lists li').css('display', 1);
						$(this).find('.lists li').show();
						
						return;
					}
					
					let lis = $(this).find('.lists li');
					
					for(let i=0; i<lis.length; i++) {
						if($(lis[i]).data('searchMatch')) {
							return ;
						}
					}
					
					$(this).css('opacity', opacity);
					
					if(hide) {
						$(this).hide();
					}
				});
				
				return this;
			};
			
			/**
			 * 高亮搜索关键字
			 * @param str
			 * @returns {string}
			 */
			this.hilightKeywords = function(str) {
				if(!str || str.length==0) {
					return '';
				}
				
				let newStr = str.toLowerCase();
				let index=0;
				let keyword = this._searchText.toLowerCase();
				let klen = keyword.length;
				let segs = [];
				
			 	while((index = newStr.indexOf(keyword)) != -1) {
			 		let content = Core.htmlEncode(str.substr(index, klen));
			 		let searchIndex = this.getKeywordCountCurrent();
					this.increaseKeywordCountCurrent();
					segs.push(Core.htmlEncode(str.substr(0, index)));
					segs.push(`<span class='search-item-hilight' data-search-index="${searchIndex}">${content}</span>`);
					this._keywordCount ++;
					str = str.substr(index+klen);
					newStr = newStr.substr(index+klen);
				}
				
				return segs.join('') + Core.htmlEncode(str);
			};
			
			this.htmlSearchToggle = function () {
				_search();
			};
		};
	})();
	
	
	$('#search_input').keyup(function (e) {
		if(e.keyCode == COREVAR.KEYS.ENTER) {
			_search();
		} else {
			if(SearchController.KeyupTimer) {
				clearTimeout(SearchController.KeyupTimer);
			}
			
			SearchController.KeyupTimer = setTimeout(_search, 200);
		}
	}).focus(function () {
		$(this).select();
	});
	
	function _search() {
		let search_input = $('#search_input');
		
		if(search_input.val() == '') {
			SearchController.quitSearch();
		} else {
			SearchController.search(search_input.val());
		}
	}
	
	$('#search_commit').click(_search);
	$('#hide_not_match_result').click(function () {
		SearchController.hideEmptyGroup($(this).prop('checked'));
	});
})(jQuery);
